# backend/core/captcha.py
from PIL import Image, ImageDraw
import random
import base64
from io import BytesIO
import logging
import os
from pathlib import Path
import re

logger = logging.getLogger(__name__)

BASE_DIR = Path(__file__).parent.parent.parent
BACKGROUNDS_DIR = BASE_DIR / "static" / "captcha" / "backgrounds"
SLIDERS_DIR = BASE_DIR / "static" / "captcha" / "sliders"

print(f"📁 背景图目录: {BACKGROUNDS_DIR.absolute()}")
print(f"📁 滑块图目录: {SLIDERS_DIR.absolute()}")


def load_matching_images():
    """加载对应的背景图和滑块图"""
    captcha_groups = {}

    # 扫描背景图
    for bg_file in BACKGROUNDS_DIR.glob("group_*_bg.jpg"):
        match = re.match(r"(group_\d+)_bg\.jpg", bg_file.name)
        if match:
            group_id = match.group(1)
            captcha_groups[group_id] = {
                'background': bg_file,
                'sliders': []  # 存储滑块文件和对应的位置
            }

    # 扫描对应的滑块图并记录位置
    for slider_file in SLIDERS_DIR.glob("group_*_slider_*.png"):
        # 解析文件名：group_01_slider_1_pos40.png
        match = re.match(r"(group_\d+)_slider_(\d+)_pos(\d+)\.png", slider_file.name)
        if match:
            group_id = match.group(1)
            slider_index = int(match.group(2))
            position_x = int(match.group(3))  # 从文件名中提取位置

            if group_id in captcha_groups:
                captcha_groups[group_id]['sliders'].append({
                    'file': slider_file,
                    'position_x': position_x,
                    'position_y': 60  # 固定的y位置
                })

    # 确保每组都有背景图和滑块图
    valid_groups = {}
    for group_id, group_data in captcha_groups.items():
        if group_data['background'].exists() and len(group_data['sliders']) > 0:
            valid_groups[group_id] = group_data

    print(f"✅ 找到 {len(valid_groups)} 组对应的验证码图片")

    # 打印调试信息
    for group_id, group_data in valid_groups.items():
        print(f"   {group_id}: {len(group_data['sliders'])} 个滑块")
        for slider in group_data['sliders']:
            print(f"     - {slider['file'].name} -> 位置: {slider['position_x']}px")

    return valid_groups


# 预加载对应的图片组
CAPTCHA_GROUPS = load_matching_images()


def create_slider_captcha() -> (int, str, str):
    """生成对应的滑块验证码"""
    try:
        if not CAPTCHA_GROUPS:
            print("⚠️ 没有找到对应的验证码图片，使用默认生成方式")
            return create_default_captcha()

        # 随机选择一组
        group_id = random.choice(list(CAPTCHA_GROUPS.keys()))
        group_data = CAPTCHA_GROUPS[group_id]

        # 从该组中随机选择一个滑块（包含位置信息）
        slider_data = random.choice(group_data['sliders'])
        correct_x = slider_data['position_x']
        slider_file = slider_data['file']

        print(f"🎲 选择验证码组: {group_id}")
        print(f"🎯 正确X位置: {correct_x}px")
        print(f"📁 使用滑块图: {slider_file.name}")

        # 加载背景图
        background = Image.open(group_data['background']).convert('RGB')

        # 在背景图上创建缺口（使用正确的位置）
        bg_with_hole = create_hole_in_background(background, correct_x, 60)

        # 加载对应的滑块图
        slider = Image.open(slider_file).convert('RGBA')

        # 将图像转为 base64
        bg_img_base64 = image_to_base64(bg_with_hole)
        slider_img_base64 = image_to_base64(slider)

        print("✅ 使用对应图片生成验证码成功")
        return correct_x, bg_img_base64, slider_img_base64

    except Exception as e:
        logger.error(f"对应滑块验证码生成失败: {e}")
        print(f"❌ 对应图片生成失败: {e}")
        return create_default_captcha()


def create_hole_in_background(background: Image.Image, x: int, y: int) -> Image.Image:
    """在背景图上创建缺口"""
    bg_copy = background.copy()
    draw = ImageDraw.Draw(bg_copy)

    # 创建缺口（白色矩形）
    hole_color = (255, 255, 255)  # 纯白色
    draw.rectangle([
        x, y,
        x + 50,  # 滑块宽度
        y + 30  # 滑块高度
    ], fill=hole_color)

    # 添加边框使缺口更明显
    draw.rectangle([
        x, y,
        x + 50,
        y + 30
    ], outline=(200, 200, 200), width=2)

    return bg_copy


def create_default_captcha() -> (int, str, str):
    """默认的验证码生成方式（备用）"""
    print("🛠️ 使用默认验证码生成方式")

    IMAGE_WIDTH, IMAGE_HEIGHT = 300, 150
    # 生成合理的x位置（与图片生成器一致）
    slider_x = random.choice([40, 100, 160, 220])
    slider_y = 60  # 固定的y位置

    # 创建背景图
    background = Image.new('RGB', (IMAGE_WIDTH, IMAGE_HEIGHT), (240, 240, 240))
    draw = ImageDraw.Draw(background)

    # 添加纹理
    for _ in range(100):
        x = random.randint(0, IMAGE_WIDTH)
        y = random.randint(0, IMAGE_HEIGHT)
        size = random.randint(2, 5)
        color = (
            random.randint(180, 220),
            random.randint(180, 220),
            random.randint(180, 220)
        )
        draw.ellipse([x, y, x + size, y + size], fill=color)

    # 在背景图上绘制缺口（白色矩形）
    draw.rectangle([
        slider_x, slider_y,
        slider_x + 50, slider_y + 30
    ], fill=(255, 255, 255))

    # 添加缺口边框
    draw.rectangle([
        slider_x, slider_y,
        slider_x + 50, slider_y + 30
    ], outline=(200, 200, 200), width=1)

    # 创建滑块图
    slider = Image.new('RGB', (50, 30), (180, 180, 180))
    draw_slider = ImageDraw.Draw(slider)
    draw_slider.rectangle([0, 0, 49, 29], outline=(100, 100, 100), width=1)

    # 添加滑块纹理
    for _ in range(20):
        x = random.randint(5, 45)
        y = random.randint(5, 25)
        color = (
            random.randint(150, 200),
            random.randint(150, 200),
            random.randint(150, 200)
        )
        draw_slider.point([x, y], fill=color)

    bg_img_base64 = image_to_base64(background)
    slider_img_base64 = image_to_base64(slider)

    print(f"🎯 默认验证码正确位置: {slider_x}px")
    return slider_x, bg_img_base64, slider_img_base64


def image_to_base64(img: Image.Image) -> str:
    """将PIL图像转为base64字符串"""
    buffer = BytesIO()
    if img.mode == 'RGBA':
        img = img.convert('RGB')
    img.save(buffer, format="PNG")
    img_bytes = buffer.getvalue()
    return base64.b64encode(img_bytes).decode('utf-8')


def generate_token() -> str:
    """生成随机token"""
    return ''.join(random.choices('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=32))